package com.dingreading.cloud.admin.service.impl;

import com.dingreading.cloud.admin.dto.StaffRoleDto;
import com.dingreading.cloud.admin.dto.StaffRolesDto;
import com.dingreading.cloud.admin.entity.StaffRoles;
import com.dingreading.cloud.admin.entity.table.StaffRolesTableDef;
import com.dingreading.cloud.admin.mapper.StaffRolesMapper;
import com.dingreading.cloud.admin.service.AdminRoleStaffService;
import com.dingreading.cloud.admin.service.StaffRolesService;
import com.dingreading.cloud.admin.util.AdminStaffRoleUtil;
import com.dingreading.cloud.common.base.R;
import com.dingreading.cloud.common.util.PageUtil;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryCondition;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.update.UpdateChain;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

import static com.dingreading.cloud.admin.entity.table.StaffTableDef.staff;
import static com.dingreading.cloud.admin.entity.table.StoresTableDef.stores;


/**
 * 服务层实现。
 *
 * @author Administrator
 * @since 2023-11-22
 */
@Service
public class StaffRolesServiceImpl extends BaseServiceImpl<StaffRolesMapper, StaffRoles, StaffRolesTableDef> implements StaffRolesService {

    @Override
    protected StaffRolesTableDef getTable() {
        return StaffRolesTableDef.staffRoles;
    }

    @Resource
    private AdminRoleStaffService roleStaffService;

    @Override
    public Page<StaffRoleDto> pageList(PageUtil pageUtil, String storeUid, String keyword, Integer enabled) {
        QueryCondition condition = QueryCondition.createEmpty();
        if (StringUtils.isNotBlank(keyword)) {
            condition.and(staff.fullName.like(keyword)
                    .or(staff.nickName.like(keyword))
                    .or(staff.username.like(keyword))
                    .or(staff.pubPhone.like(keyword))
                    .or(staff.priPhone.like(keyword))
            );
        }
        if (StringUtils.isNotBlank(storeUid)) {
            condition.and(table.storeUid.eq(storeUid));
        }
        if (enabled != null) {
            condition.and(table.enabled.eq(enabled));
        }

        QueryWrapper wrapper = QueryWrapper.create()
                .select(table.allColumns, stores.storeName, staff.id, staff.corpUid, staff.fullName, staff.nickName,
                        staff.uid, staff.username, staff.pubPhone, staff.priPhone, staff.lastLoginTime, staff.addTime
                )
                .from(table)
                .leftJoin(staff).on(table.staffUid.eq(staff.uid))
                .leftJoin(stores).on(table.storeUid.eq(stores.uid))
                .where(condition)
                .orderBy(table.id.asc());

        return getMapper().paginateAs(Page.of(pageUtil.getPage(), pageUtil.getRows()), wrapper, StaffRoleDto.class);
    }


    @Override
    public void updateEnabledByStoreUid(String headStaffUid, String headStaffName, String storeUid, Integer enabled) {
        UpdateChain.of(StaffRoles.class)
                .set(table.enabled, enabled)
                .where(table.storeUid.eq(storeUid))
                .update();
    }

    @Override
    public void updateEnabledByStaffUid(String headStaffUid, String headStaffName, String staffUid, Integer enabled) {
        UpdateChain.of(StaffRoles.class)
                .set(table.enabled, enabled)
                .set(table.lastStaffUid, headStaffUid)
                .set(table.lastStaffName, headStaffName)
                .where(table.staffUid.eq(staffUid))
                .update();
    }

    @Override
    public List<StaffRolesDto> getByStaffUid(String staffUid) {
        QueryWrapper wrapper = QueryWrapper.create()
                .where(table.staffUid.eq(staffUid));
        return getMapper().selectListWithRelationsByQueryAs(wrapper, StaffRolesDto.class);
    }

    @Override
    public StaffRolesDto getByIdDto(Long id) {
        QueryWrapper wrapper = QueryWrapper.create()
                .where(table.id.eq(id));
        return getMapper().selectOneWithRelationsByQueryAs(wrapper, StaffRolesDto.class);
    }

    @Override
    public StaffRoles getByStaffUidAndStoreUid(String storeUid, String staffUid) {
        QueryCondition condition = QueryCondition.createEmpty()
                .and(table.storeUid.eq(storeUid))
                .and(table.staffUid.eq(staffUid));
        return getMapper().selectOneByCondition(condition);
    }


    @Override
    public R<Object> editRoleBean(
            String headStaffUid, String headStaffName, Long id, String storeUid, String staffUid,
            String roleName, List<Integer> roleList, Integer isHeadquarterStaff, Integer isStoreStaff, Integer inStoreService
    ) {
        if (StringUtils.isBlank(storeUid)) {
            return R.fail("门店uid为空！");
        }
        if (StringUtils.isBlank(staffUid)) {
            return R.fail("所选员工uid为空！");
        }
        if (StringUtils.isBlank(roleName)) {
            return R.fail("请填写角色名！");
        }
        if (CollectionUtils.isEmpty(roleList)) {
            return R.fail("请选择员工角色！");
        }

        // 员工是否是超管
        List<String> identifyList = roleStaffService.identifyListByStaffUid(headStaffUid);
        boolean superAdmin = AdminStaffRoleUtil.isSuperAdmin(identifyList);
        if (superAdmin) {
            if (isHeadquarterStaff == null) {
                return R.fail("请选择是否有管理界面！");
            }
            if (isStoreStaff == null) {
                return R.fail("请选择是否是门店员工！");
            }
            if (inStoreService == null) {
                return R.fail("请选择是否在门店代课！");
            }
        } else {
            // 非超管设置默认值
            if (isHeadquarterStaff == null) {
                isHeadquarterStaff = 0;
            }
            if (isStoreStaff == null) {
                isStoreStaff = 1;
            }
            if (inStoreService == null) {
                inStoreService = 1;
            }
        }

        if (id == null) {
            StaffRoles rolesStoreUid = getByStaffUidAndStoreUid(storeUid, staffUid);
            if (rolesStoreUid != null)
                return R.fail("员工在此门店已设置角色！");

            StaffRoles staffRoles = new StaffRoles();
            staffRoles.setStoreUid(storeUid);
            staffRoles.setStaffUid(staffUid);
            staffRoles.setRoleName(roleName);
            String roles = roleList.stream().sorted(Comparator.reverseOrder()).map(String::valueOf).collect(Collectors.joining(","));
            staffRoles.setRoles(roles);
            staffRoles.setIsHeadquarterStaff(isHeadquarterStaff);
            staffRoles.setIsStoreStaff(isStoreStaff);
            staffRoles.setInStoreService(inStoreService);
            staffRoles.setEnabled(1);
            staffRoles.setAddStaffUid(headStaffUid);
            staffRoles.setAddStaffName(headStaffName);
            staffRoles.setLastStaffUid(headStaffUid);
            staffRoles.setLastStaffName(headStaffName);
            boolean save = save(staffRoles);
            if (!save)
                return R.fail("保存员工角色失败！");
        } else {
            StaffRoles rolesStoreUid = getByStaffUidAndStoreUid(storeUid, staffUid);
            if (rolesStoreUid != null && !rolesStoreUid.getId().equals(id))
                return R.fail("员工在此门店已设置角色！");

            String roles = roleList.stream().sorted(Comparator.reverseOrder()).map(String::valueOf).collect(Collectors.joining(","));

            QueryCondition condition = table.storeUid.eq(storeUid)
                    .and(table.staffUid.eq(staffUid))
                    .and(table.id.eq(id));

            UpdateChain<StaffRoles> updateChain = UpdateChain.of(StaffRoles.class);
            updateChain.set(table.roleName, roleName)
                    .set(table.roles, roles)
                    .set(table.lastStaffUid, headStaffUid)
                    .set(table.lastStaffName, headStaffName);
            if (superAdmin) {
                updateChain.set(table.isHeadquarterStaff, isHeadquarterStaff)
                        .set(table.isStoreStaff, isStoreStaff)
                        .set(table.inStoreService, inStoreService);
            }
            boolean update = updateChain.where(condition)
                    .update();
            if (!update)
                return R.fail("更新员工角色失败！");
        }
        return R.ok();
    }

    @Override
    public boolean updateRoleBean(
            String headStaffUid, String headStaffName, String storeUid, String staffUid, String roleName,
            List<Integer> roleList, boolean superAdmin, Integer isHeadquarterStaff, Integer isStoreStaff, Integer inStoreService
    ) {
        QueryCondition condition = table.storeUid.eq(storeUid)
                .and(table.staffUid.eq(staffUid));
        String roles = roleList.stream().sorted(Comparator.reverseOrder()).map(String::valueOf).collect(Collectors.joining(","));
        UpdateChain<StaffRoles> updateChain = UpdateChain.of(StaffRoles.class);
        updateChain.set(table.roleName, roleName)
                .set(table.roles, roles)
                .set(table.lastStaffUid, headStaffUid)
                .set(table.lastStaffName, headStaffName);
        if (superAdmin) {
            updateChain.set(table.isHeadquarterStaff, isHeadquarterStaff)
                    .set(table.isStoreStaff, isStoreStaff)
                    .set(table.inStoreService, inStoreService);
        }
        return updateChain.where(condition)
                .update();
    }

    @Override
    public R<Object> updateEnabled(String headStaffUid, String headStaffName, Long id, Integer enabled) {
        boolean update = UpdateChain.of(StaffRoles.class)
                .set(table.enabled, enabled)
                .set(table.lastStaffUid, headStaffUid)
                .set(table.lastStaffName, headStaffName)
                .where(table.id.eq(id))
                .update();
        if (!update)
            return R.fail();

        return R.ok();
    }


}
